/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * PhotosFrame.java
 *
 * Created on 31.05.2011, 20:48:53
 */
package ua.pp.bizon.yandex.nb;

import ua.pp.bizon.yandex.api.IAppService;
import ua.pp.bizon.yandex.api.IJobExecutor;
import ua.pp.bizon.yandex.api.IJobFactory;
import ua.pp.bizon.yandex.api.IMainFrame;
import ua.pp.bizon.yandex.api.Job;
import ua.pp.bizon.yandex.api.JobInfo;
import ua.pp.bizon.yandex.api.ObjectLookup;
import ua.pp.bizon.yandex.api.WindowManager;
import ua.pp.bizon.yandex.api.impl.Activity;
import ua.pp.bizon.yandex.api.impl.Element;
import ua.pp.bizon.yandex.api.impl.EventSupport.ChangeListener;
import ua.pp.bizon.yandex.api.impl.UploadFilesJob;
import ua.pp.bizon.yandex.jmx.IJMXService;
import ua.pp.bizon.yandex.nb.model.LocalNode;
import ua.pp.bizon.yandex.nb.model.LocalPhoto;
import ua.pp.bizon.yandex.nb.model.RemoteAlbumNode;
import ua.pp.bizon.yandex.nb.model.RemoteNode;
import ua.pp.bizon.yandex.uploader.atom.AlbumsList;
import ua.pp.bizon.yandex.uploader.atom.EntryAlbum;

import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.LinkedList;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import org.apache.commons.logging.LogFactory;

/**
 * 
 * @author Bizon
 */
public class PhotosFrame extends javax.swing.JFrame implements IMainFrame {

	private final class RemotePhotoListRefresh implements Job {
		private final TreePath selection;

		private RemotePhotoListRefresh(TreePath selection) {
			this.selection = selection;
		}

		@Override
		public void run() {
			if (selection != null && selection.getLastPathComponent() instanceof RemoteAlbumNode) {
				RemoteAlbumNode remoteNode = (RemoteAlbumNode) selection.getLastPathComponent();
				remoteList.setModel(new DefaultComboBoxModel(model.getPhotosBySelection(remoteNode)));
			} else {
				remoteList.setModel(new DefaultComboBoxModel());
			}
		}
	}

	private final class Popup extends MouseAdapter {
		private void myPopupEvent(MouseEvent e) {
			int x = e.getX();
			int y = e.getY();
			JTree tree = (JTree) e.getSource();
			TreePath path = tree.getPathForLocation(x, y);
			if (path == null)
				return;

			tree.setSelectionPath(path);

			JPopupMenu popup = new JPopupMenu();
			popup.add(new RefreshAction());
			popup.show(tree, x, y);
		}

		public void mousePressed(MouseEvent e) {
			if (e.isPopupTrigger())
				myPopupEvent(e);
		}

		public void mouseReleased(MouseEvent e) {
			if (e.isPopupTrigger())
				myPopupEvent(e);
		}
	}

	private final class RefreshAction extends AbstractAction implements JobInfo {

		private static final long serialVersionUID = 4593742468252916570L;

		public RefreshAction() {
			putValue(NAME, "Refresh");
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			ObjectLookup.lookup(IJobExecutor.class).exec(this);
		}

		@Override
		public void run() {
			ObjectLookup.lookup(IAppService.class).create();
			refreshRemote();
		}

		@Override
		public Element getState() {
			Element element = new Element();
			element.setActivity(Activity.READ_SERVICE_DOCUMENT);
			return element;
		}
	}

	private PhotosNbModel model = new PhotosNbModel();

	private static final long serialVersionUID = 7203023843958292384L;

	/** Creates new form PhotosFrame */
	public PhotosFrame() {
		LogFactory.getLog(getClass()).trace("PhotosFrame created", new Exception());
		initComponents();
		progressPanel1.setVisible(false);
		jobsPanel1.setVisible(false);
		setExtendedState(MAXIMIZED_BOTH);
		MouseAdapter ma = new Popup();
		remoteTree.addMouseListener(ma);
		/*
		 * progressPanel1.addAncestorListener(new AncestorListener() {
		 * 
		 * @Override public void ancestorAdded(AncestorEvent event) {
		 * LogFactory.getLog(getClass()).info("pack"); pack();
		 * setExtendedState(MAXIMIZED_BOTH); }
		 * 
		 * @Override public void ancestorRemoved(AncestorEvent event) {
		 * LogFactory.getLog(getClass()).info("pack"); pack();
		 * setExtendedState(MAXIMIZED_BOTH); }
		 * 
		 * @Override public void ancestorMoved(AncestorEvent event) {
		 * LogFactory.getLog(getClass()).info("pack"); pack();
		 * setExtendedState(MAXIMIZED_BOTH); } });
		 */
	}

	protected String getSelectedDrive() {
		return driveComboBox.getSelectedItem() == null ? "" : driveComboBox.getSelectedItem().toString();
	}

	protected DefaultTreeModel getLocalTreeModel(String selectedItem) {
		return new DefaultTreeModel(model.getRightTree(selectedItem));
	}

	protected DefaultComboBoxModel getDriveComboBoxModel() {
		return new DefaultComboBoxModel(model.getDrives());
	}

	protected DefaultTreeModel getCurrentRemoteModel() {
		RemoteNode leftTree = model.getLeftTree();
		final DefaultTreeModel defaultTreeModel = new DefaultTreeModel(leftTree);
		leftTree.addListener(new ChangeListener() {

			@Override
			public void dataChanged() {
				defaultTreeModel.reload();
			}
		});
		return defaultTreeModel;
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	// <editor-fold defaultstate="collapsed"
	// desc="Generated Code">//GEN-BEGIN:initComponents
	private void initComponents() {
		java.awt.GridBagConstraints gridBagConstraints;

		remoteScrollPane = new javax.swing.JScrollPane();
		remoteTree = new javax.swing.JTree();
		localScrollPane = new javax.swing.JScrollPane();
		localTree = new javax.swing.JTree();
		remoteListScrollPane = new javax.swing.JScrollPane();
		remoteList = new javax.swing.JList();
		localListScrollPane = new javax.swing.JScrollPane();
		localList = new javax.swing.JList();
		toolBar = new javax.swing.JToolBar();
		createRemoteFolderButton = new javax.swing.JButton();
		jSeparator1 = new javax.swing.JToolBar.Separator();
		photosLabel = new javax.swing.JLabel();
		toButton = new javax.swing.JButton();
		fromButton = new javax.swing.JButton();
		jSeparator2 = new javax.swing.JToolBar.Separator();
		foldersLabel = new javax.swing.JLabel();
		toFolderButton = new javax.swing.JButton();
		fromFolderButton = new javax.swing.JButton();
		jSeparator3 = new javax.swing.JToolBar.Separator();
		reloginButton = new javax.swing.JButton();
		driveComboBox = new javax.swing.JComboBox();
		progressPanel1 = new ua.pp.bizon.yandex.nb.ProgressPanel();
		jobsPanel1 = new ua.pp.bizon.yandex.nb.JobsPanel();

		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
		getContentPane().setLayout(new java.awt.GridBagLayout());

		remoteTree.setModel(getCurrentRemoteModel());
		remoteTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
			public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
				remoteTreeValueChanged(evt);
			}
		});
		remoteScrollPane.setViewportView(remoteTree);

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 3;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.ipadx = 100;
		gridBagConstraints.ipady = 428;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
		getContentPane().add(remoteScrollPane, gridBagConstraints);

		localTree.setModel(getLocalTreeModel(getSelectedDrive()));
		localTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
			public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
				localTreeValueChanged(evt);
			}
		});
		localScrollPane.setViewportView(localTree);

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 3;
		gridBagConstraints.gridy = 3;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.ipadx = 100;
		gridBagConstraints.ipady = 428;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
		getContentPane().add(localScrollPane, gridBagConstraints);

		remoteListScrollPane.setPreferredSize(new java.awt.Dimension(74, 322));

		remoteListScrollPane.setViewportView(remoteList);

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 1;
		gridBagConstraints.gridy = 3;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.ipadx = 100;
		gridBagConstraints.ipady = 428;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
		getContentPane().add(remoteListScrollPane, gridBagConstraints);

		localListScrollPane.setPreferredSize(new java.awt.Dimension(74, 322));

		localListScrollPane.setViewportView(localList);

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 2;
		gridBagConstraints.gridy = 3;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.ipadx = 100;
		gridBagConstraints.ipady = 428;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.weighty = 1.0;
		gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
		getContentPane().add(localListScrollPane, gridBagConstraints);

		toolBar.setRollover(true);

		createRemoteFolderButton.setText("Create remote folder");
		createRemoteFolderButton.setFocusable(false);
		createRemoteFolderButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
		createRemoteFolderButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
		createRemoteFolderButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				createRemoteFolderButtonActionPerformed(evt);
			}
		});
		toolBar.add(createRemoteFolderButton);
		toolBar.add(jSeparator1);

		photosLabel.setText("Photos:");
		toolBar.add(photosLabel);

		toButton.setText("<=");
		toButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				toButtonActionPerformed(evt);
			}
		});
		toolBar.add(toButton);

		fromButton.setText("=>");
		fromButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				fromButtonActionPerformed(evt);
			}
		});
		toolBar.add(fromButton);
		toolBar.add(jSeparator2);

		foldersLabel.setText("Folders:");
		toolBar.add(foldersLabel);

		toFolderButton.setText("<=");
		toFolderButton.setFocusable(false);
		toFolderButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
		toFolderButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
		toFolderButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				toFolderButtonActionPerformed(evt);
			}
		});
		toolBar.add(toFolderButton);

		fromFolderButton.setText("=>");
		fromFolderButton.setFocusable(false);
		fromFolderButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
		fromFolderButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
		fromFolderButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				fromFolderButtonActionPerformed(evt);
			}
		});
		toolBar.add(fromFolderButton);
		toolBar.add(jSeparator3);

		reloginButton.setText("relogin");
		reloginButton.setFocusable(false);
		reloginButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
		reloginButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
		reloginButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				reloginButtonActionPerformed(evt);
			}
		});
		toolBar.add(reloginButton);

		driveComboBox.setModel(getDriveComboBoxModel());
		driveComboBox.addItemListener(new java.awt.event.ItemListener() {
			public void itemStateChanged(java.awt.event.ItemEvent evt) {
				driveComboBoxItemStateChanged(evt);
			}
		});
		toolBar.add(driveComboBox);

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.gridwidth = 4;
		gridBagConstraints.ipadx = 5;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
		gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
		getContentPane().add(toolBar, gridBagConstraints);
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 2;
		gridBagConstraints.gridwidth = 4;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		getContentPane().add(progressPanel1, gridBagConstraints);
		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 1;
		gridBagConstraints.gridwidth = 4;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		getContentPane().add(jobsPanel1, gridBagConstraints);

		pack();
	}// </editor-fold>//GEN-END:initComponents

	private void driveComboBoxItemStateChanged(java.awt.event.ItemEvent evt) {// GEN-FIRST:event_driveComboBoxItemStateChanged
		localTree.setModel(getLocalTreeModel(getSelectedDrive()));
	}// GEN-LAST:event_driveComboBoxItemStateChanged

	private void reloginButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_reloginButtonActionPerformed
		ObjectLookup.lookup(WindowManager.class).login(false);
	}// GEN-LAST:event_reloginButtonActionPerformed

	private void toFolderButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_toFolderButtonActionPerformed
		TreePath fromSelection = localTree.getSelectionPath();
		if (fromSelection != null && fromSelection.getLastPathComponent() instanceof LocalNode) {
			LocalNode localNode = (LocalNode) fromSelection.getLastPathComponent();
			File from = localNode.getFile();
			AlbumsList to = null;
			TreePath selection = remoteTree.getSelectionPath();
			if (selection != null && selection.getLastPathComponent() instanceof RemoteNode) {
				RemoteNode remoteNode = (RemoteNode) selection.getLastPathComponent();
				to = remoteNode.getAlbum();
			} else {
				to = ObjectLookup.lookup(IAppService.class).get().getAlbumsList();
			}
			ObjectLookup.lookup(IJMXService.class).getQuery().addActivity(ObjectLookup.lookup(IJobFactory.class).uploadFolder(from, to));
		} else {
			JOptionPane.showMessageDialog(this, "nothing to copy");
		}
	}// GEN-LAST:event_toFolderButtonActionPerformed

	private void fromFolderButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_fromFolderButtonActionPerformed
		// TODO add your handling code here:
	}// GEN-LAST:event_fromFolderButtonActionPerformed

	private void remoteTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {// GEN-FIRST:event_remoteTreeValueChanged
		final TreePath selection = evt.getNewLeadSelectionPath();
		remoteList.setModel(new DefaultComboBoxModel(new Object[] { "please wait" }));
		new Thread(new RemotePhotoListRefresh(selection)).start(); // TODO FIX!!
	}// GEN-LAST:event_remoteTreeValueChanged

	private void localTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {// GEN-FIRST:event_localTreeValueChanged
		TreePath selection = evt.getNewLeadSelectionPath();
		if (selection != null && selection.getLastPathComponent() instanceof LocalNode) {
			LocalNode localNode = (LocalNode) selection.getLastPathComponent();
			localList.setModel(new DefaultComboBoxModel(model.getPhotosBySelection(localNode)));
		} else {
			localList.setModel(new DefaultComboBoxModel());
		}
	}// GEN-LAST:event_localTreeValueChanged

	private void toButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_toButtonActionPerformed
		Object[] res = localList.getSelectedValues();
		List<File> files = new LinkedList<File>();
		if (res != null && res.length > 0) {
			for (Object o : res) {
				if (o instanceof LocalPhoto) {
					files.add(((LocalPhoto) o).getFile());
				}
			}
		} else {
			JOptionPane.showMessageDialog(null, "Select photos first");
			return;
		}
		TreePath path = remoteTree.getSelectionPath();
		EntryAlbum to = null;
		if (path != null && path.getLastPathComponent() != null && path.getLastPathComponent() instanceof RemoteAlbumNode) {
			to = ((RemoteAlbumNode) path.getLastPathComponent()).getAlbum();
		}
		if (to != null) {
			final IJobExecutor executor = ObjectLookup.lookup(IJobExecutor.class);
			executor.exec(new UploadFilesJob(files, to, executor));
		} else {
			JOptionPane.showMessageDialog(null, "Select remote album first");
		}
	}// GEN-LAST:event_toButtonActionPerformed

	private void createRemoteFolderButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_createRemoteFolderButtonActionPerformed
		String foldername = JOptionPane.showInputDialog(this, "Input new name", "new folder");
		TreePath selection = remoteTree.getSelectionPath();
		if (selection == null) {
			ObjectLookup.lookup(IAppService.class).get().getAlbumsList().createAlbum(foldername);
		} else {
			RemoteNode node = (RemoteNode) selection.getLastPathComponent();
			node.getAlbum().createAlbum(foldername);
		}
		refreshRemote();
	}// GEN-LAST:event_createRemoteFolderButtonActionPerformed

	protected void refreshRemote() {
		((DefaultTreeModel) remoteTree.getModel()).reload();
	}

	private void fromButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_fromButtonActionPerformed
		// TODO add your handling code here:
	}// GEN-LAST:event_fromButtonActionPerformed

	// Variables declaration - do not modify//GEN-BEGIN:variables
	private javax.swing.JButton createRemoteFolderButton;
	private javax.swing.JComboBox driveComboBox;
	private javax.swing.JLabel foldersLabel;
	private javax.swing.JButton fromButton;
	private javax.swing.JButton fromFolderButton;
	private javax.swing.JToolBar.Separator jSeparator1;
	private javax.swing.JToolBar.Separator jSeparator2;
	private javax.swing.JToolBar.Separator jSeparator3;
	private ua.pp.bizon.yandex.nb.JobsPanel jobsPanel1;
	private javax.swing.JList localList;
	private javax.swing.JScrollPane localListScrollPane;
	private javax.swing.JScrollPane localScrollPane;
	private javax.swing.JTree localTree;
	private javax.swing.JLabel photosLabel;
	private ua.pp.bizon.yandex.nb.ProgressPanel progressPanel1;
	private javax.swing.JButton reloginButton;
	private javax.swing.JList remoteList;
	private javax.swing.JScrollPane remoteListScrollPane;
	private javax.swing.JScrollPane remoteScrollPane;
	private javax.swing.JTree remoteTree;
	private javax.swing.JButton toButton;
	private javax.swing.JButton toFolderButton;
	private javax.swing.JToolBar toolBar;

	// End of variables declaration//GEN-END:variables

	public ProgressPanel getProgressPanel() {
		return progressPanel1;
	}
}
